package edu.buaa.traffic;

import com.aliyun.openservices.aliyun.log.producer.Producer;
import edu.buaa.common.BenchmarkReader;
import edu.buaa.common.TxResultProcessor;
import edu.buaa.common.client.DBProxy;
import edu.buaa.common.client.Neo4jExecutorClient;
import edu.buaa.common.transaction.AbstractTransaction;
import edu.buaa.common.client.TGraphExecutorClient;
import edu.buaa.energy.client.MariaDBClient;
import edu.buaa.traffic.client.PostgreSQLExecutorClient;
import edu.buaa.utils.Helper;

import java.io.File;
import java.util.Calendar;

public class BenchmarkRunner {

    public static void main(String[] args) {
        String benchmarkFileName = Helper.mustEnv("BENCHMARK_FILE_INPUT");
        String dbType = Helper.mustEnv("DB_TYPE");
        int maxConnCnt = Integer.parseInt(Helper.mustEnv("MAX_CONNECTION_CNT"));
        String dbHost = Helper.mustEnv("DB_HOST");
        boolean verifyResult = Boolean.parseBoolean(Helper.mustEnv("VERIFY_RESULT"));

        try {
            DBProxy client = initClient(dbType, dbHost, maxConnCnt);
            String serverVersion = client.testServerClientCompatibility();
            Producer logger = Helper.getLogger();
            TxResultProcessor post = new TxResultProcessor(getTestName(dbType, serverVersion), Helper.codeGitVersion());
            post.setLogger(logger);
            post.setVerifyResult(verifyResult);
            BenchmarkReader reader = new BenchmarkReader(new File(benchmarkFileName));
            while (reader.hasNext()) {
                AbstractTransaction tx = reader.next();
                post.process(client.execute(tx), tx);
            }
            reader.close();
            client.close();
            logger.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static DBProxy initClient(String dbType, String dbHost, int maxConnCnt) throws Exception {
        switch (dbType.toLowerCase()) {
            case "mariadb": return new MariaDBClient(dbHost, maxConnCnt);
            case "postgresql": return new PostgreSQLExecutorClient(dbHost, maxConnCnt);
            case "tgraph_kernel": return new TGraphExecutorClient(dbHost, maxConnCnt);
            case "neo4j1":
                return new Neo4jExecutorClient(dbHost, 9833, maxConnCnt);
            case "neo4j2":
                return new Neo4jExecutorClient(dbHost, 9866, maxConnCnt);
            default:
                throw new UnsupportedOperationException();
        }
    }

    private static String getTestName(String dbType, String dbVersion){
        Calendar c = Calendar.getInstance();
        return "B_"+dbType.toLowerCase()+"("+dbVersion+")_"+
                c.get(Calendar.YEAR)+"."+(c.get(Calendar.MONTH)+1)+"."+c.get(Calendar.DAY_OF_MONTH)+"_"+
                c.get(Calendar.HOUR_OF_DAY)+":"+c.get(Calendar.MINUTE);
    }


}
